﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


using Microsoft.Xna.Framework;

namespace SurvivalStrategy
{
    public class FilesHelper
    {

        //Metoda wczytuje swiat z podanej sciezki
        public static World ReadWorld(string path)
        {
            //rozpoczecie wczytywania danych
            string filePath = path + "n0b";
            StreamReader streamReader = new StreamReader(filePath);

            //stworzenie nowego swiata na podstawie ktorego bedziemy odtwarzac stary;
            World world;

            try
            {
                //wczytanie podstawowych danych
                string[] standardInfo = GetStringArray(streamReader.ReadLine());
                World.Width = int.Parse(standardInfo[0]);
                World.Height = int.Parse(standardInfo[1]);

                //zainicjalizowanie swiatu wedlug pobranych parametrów
                world = new World();

                //uzupelnienie swiata parametrami
                while (!streamReader.EndOfStream)
                {
                    string[] nextLine = GetStringArray(streamReader.ReadLine());
                    float x = float.Parse(nextLine[0]);         //pozycja
                    float y = float.Parse(nextLine[1]);
                    float z = float.Parse(nextLine[2]);
                    float rotX = float.Parse(nextLine[3]);      //rotacja
                    float rotY = float.Parse(nextLine[4]);
                    float rotZ = float.Parse(nextLine[5]);
                    int typeID = int.Parse(nextLine[6]);        //type elementu

                    //element dodawany jest do swiata
                    world.AddElement(new WorldData.WorldElement(new Vector3(x, y, z), new Vector3(rotX, rotY, rotZ), typeID));
                }
            }
            catch
            {
                throw new Exception("Nieprawidłowy format pliku zapisu");
            }

            return world;
        }

        //Metoda zapisuje aktualny swiat
        public static void SaveWorld(World world, string path)
        {
            string filePath = path + "n0b";

            //rozpoczecie zapisywania pliku
            StreamWriter streamWriter = new StreamWriter(filePath);

            //zapisywanie podstawowych danych o swiecie
            streamWriter.WriteLine(World.Width + " " + World.Height);

            //zapisywanie wszystkich elementow swiata
            foreach (WorldData.WorldChunk chunk in world.Chunks)
            {
                foreach (List<WorldData.WorldElement> elementList in chunk.ChunkData)
                    foreach (WorldData.WorldElement element in elementList)
                    {
                        string nextLine = element.Position.X + " " + element.Position.Y + " " + element.Position.Z + " "
                                        + element.Rotation.X + " " + element.Rotation.Y + " " + element.Rotation.Z + " "
                                        + element.TypeID;

                        streamWriter.WriteLine(nextLine);
                    }
            }
            streamWriter.Close();
        }

        //Metoda pobiera wszystkie typy elementow i dodaje je do odpowiedniej kolekcji
        public static void ReadElementsTypes(string path)
        {
            string filePath = path + "n0b";
            StreamReader streamReader = new StreamReader(filePath);

            //wczytuje wszystkie rekordy z podanego pliku i dodaje je do slownika
            //World.ElementsTypes.Add(ID, new WorldData.ElementType(ID, same stuff);
            try
            {
                while (!streamReader.EndOfStream)
                {
                    string[] nextLine = GetStringArray(streamReader.ReadLine());
                    string[] colliderStrings = GetStringArray(streamReader.ReadLine());
                    WorldData.Colliders.Collider collider = new WorldData.Colliders.Collider();
                    switch (int.Parse(nextLine[0]))
                    {
                        case 0:
                            collider = WorldData.Colliders.RectangleCollider.Parse(colliderStrings);
                            break;
                    }

                    World.ElementsTypes.Add(int.Parse(nextLine[1]), new WorldData.ElementType(int.Parse(nextLine[1]), nextLine[2], int.Parse(nextLine[3]),
                            new Vector3(float.Parse(nextLine[4]), float.Parse(nextLine[5]), float.Parse(nextLine[6])), bool.Parse(nextLine[7]), collider));
                }
            }
            catch
            {
                throw new Exception("Nieprawidłowy format pliku zapisu");
            }
        }

        //Metoda zapisuje wszystkie typy elementów do pliku
        public static void SaveElementsTypes(string path)
        {
            string filePath = path + "n0b";
            StreamWriter streamWriter = new StreamWriter(filePath);

            foreach (int id in World.ElementsTypes.Keys)
            {
                int colideId = 0;
                if (World.ElementsTypes[id].CollideType is WorldData.Colliders.RectangleCollider) colideId = 0;

                string nextLine = colideId + " " + World.ElementsTypes[id].ID + " " + World.ElementsTypes[id].Name + " " + World.ElementsTypes[id].TextureID + " " +
                    World.ElementsTypes[id].Size.X + " " + World.ElementsTypes[id].Size.Y + " " + World.ElementsTypes[id].Size.Z + " " + World.ElementsTypes[id].Collidable;
                streamWriter.WriteLine(nextLine);

                switch (colideId)
                {
                    case 0:
                        Rectangle r = ((WorldData.Colliders.RectangleCollider)World.ElementsTypes[id].CollideType).rectangle;
                        nextLine = r.X + " " + r.Y + " " + r.Width + " " + r.Height;
                        break;
                }

                streamWriter.WriteLine(nextLine);
            }
            streamWriter.Close();
        }

        //Metoda pomocnicza zamieniajaca strina na liste stringow dzielac je wedlug separatorow okreslonych na stale w metodzie
        public static string[] GetStringArray(string str)
        {
            char[] separators = { ' ' };
            return str.Split(separators);
        }
    }
}
